// 语法分析器
package parser

import (
	"fmt"
	"lark/src/ast"
	"lark/src/exception"
	"lark/src/lexer"
	"strconv"
)

// 定义表达式优先级变量
const (
	_ int = iota
	LOWEST
	EQUALS            // ==
	LESSGREATER       // > or <
	LESSGREATEREQUALS // >= or <=
	SUM               // +
	PLUSMINUS         // ++ or --
	PRODUCT           // *
	PREFIX            // -X or !X
	CALL              // myFunction(X)
	INDEX             //array[index]
	ACCESS            // api.name 点号访问优先级
)

// 定义表达式优先级map
var precedences = map[lexer.TokenType]int{
	lexer.EQ:         EQUALS,
	lexer.NOT_EQ:     EQUALS,
	lexer.LT:         LESSGREATER,
	lexer.GT:         LESSGREATER,
	lexer.LARGE_GT:   LESSGREATEREQUALS,
	lexer.SMALL_GT:   LESSGREATEREQUALS,
	lexer.PLUS:       SUM,
	lexer.MINUS:      SUM,
	lexer.PLUSPLUS:   PLUSMINUS,
	lexer.MINUSMINUS: PLUSMINUS,
	lexer.SLASH:      PRODUCT,
	lexer.ASTERISK:   PRODUCT,
	lexer.LPAREN:     CALL,
	lexer.LBRACKET:   INDEX,
	lexer.DOT:        ACCESS,
}

type (
	//定义一个前缀表达式函数类型
	prefixParseFn func() ast.Expression
	//定义一个中缀表达式函数类型
	infixParseFn func(ast.Expression) ast.Expression
)

type Parser struct {
	l *lexer.Lexer

	curToken  lexer.Token //当前token
	peekToken lexer.Token //下一个token

	ErrorHandler *exception.ErrorHandler

	//定义一个前缀表达式map,里边是函数
	prefixParseFns map[lexer.TokenType]prefixParseFn

	//定义一个中缀表达式map,里边是函数
	infixParseFns map[lexer.TokenType]infixParseFn
}

func New(l *lexer.Lexer) *Parser {
	p := &Parser{
		l: l,
	}

	p.prefixParseFns = make(map[lexer.TokenType]prefixParseFn)
	p.registerPrefix(lexer.IDENT, p.parseIdentifier)
	p.registerPrefix(lexer.INT, p.parseIntegerLiteral)
	p.registerPrefix(lexer.FLOAT, p.parseFloatLiteral)
	p.registerPrefix(lexer.STRING, p.parseStringLiteral)
	/* p.registerPrefix(lexer.BANG, p.parsePrefixExpression)
	p.registerPrefix(lexer.MINUS, p.parsePrefixExpression) */
	p.registerPrefix(lexer.TRUE, p.parseBoolean)
	p.registerPrefix(lexer.FALSE, p.parseBoolean)
	p.registerPrefix(lexer.LPAREN, p.parseGroupedExpression) // (
	p.registerPrefix(lexer.IF, p.parseIfExpression)
	p.registerPrefix(lexer.FOR, p.parseForExpression)
	p.registerPrefix(lexer.FUNCTION, p.parseFunctionLiteral)
	p.registerPrefix(lexer.LBRACKET, p.parseArrayLiteral) // [
	p.registerPrefix(lexer.LBRACE, p.parseHashLiteral)    // {
	// p.registerPrefix(lexer.DOT, p.parseModuleAccess)      // .

	// 注册中缀表达式
	p.infixParseFns = make(map[lexer.TokenType]infixParseFn)
	p.registerInfix(lexer.PLUS, p.parseInfixExpression)
	p.registerInfix(lexer.MINUS, p.parseInfixExpression)
	p.registerInfix(lexer.ASTERISK, p.parseInfixExpression)
	p.registerInfix(lexer.SLASH, p.parseInfixExpression)
	p.registerInfix(lexer.EQ, p.parseInfixExpression)
	p.registerInfix(lexer.NOT_EQ, p.parseInfixExpression)
	p.registerInfix(lexer.LT, p.parseInfixExpression)
	p.registerInfix(lexer.GT, p.parseInfixExpression)
	p.registerInfix(lexer.LARGE_GT, p.parseInfixExpression) //大于等于
	p.registerInfix(lexer.SMALL_GT, p.parseInfixExpression) //小于等于

	p.registerInfix(lexer.LPAREN, p.parseCallExpression)    //(
	p.registerInfix(lexer.LBRACKET, p.parseIndexExpression) //[
	// p.registerInfix(lexer.DOT, p.parseModuleAccess)         //.

	p.nextToken()
	p.nextToken()

	// utils.Fatal("p.curToken")

	return p
}

func (p *Parser) nextToken() {
	p.curToken = p.peekToken
	p.peekToken = p.l.NextToken()
}

func (p *Parser) curTokenIs(t lexer.TokenType) bool {
	return p.curToken.Type == t
}

func (p *Parser) peekTokenIs(t lexer.TokenType) bool {
	return p.peekToken.Type == t
}

// 判断下一个token是否正确，并执行下一个token
func (p *Parser) expectPeek(t lexer.TokenType) bool {
	if p.peekTokenIs(t) {
		p.nextToken()
		return true
	} else {
		// 下一个token错误
		p.peekError(t)
		return false
	}
}

// 数组中追加错误信息
func (p *Parser) appendError(format string, arg ...interface{}) {
	msg := fmt.Sprintf(format, arg...)
	// p.errors = append(p.errors, exception.Error(msg, 0, exception.Location{Line: p.curToken.Line}))
	p.ErrorHandler.ParseError(msg, 0, p.peekToken)
}

// 下一个token错误
func (p *Parser) peekError(t lexer.TokenType) {
	// p.appendError("下一个Token应为 '%s' ,而得到的却是 '%s':'%s'", t, p.peekToken.Type, p.peekToken.Literal)
	msg := fmt.Sprintf("下一个Token应为 '%s' ,而得到的却是 '%s':'%s'", t, p.peekToken.Type, p.peekToken.Literal)
	p.ErrorHandler.ParseError(msg, 0, p.peekToken)
}

// 开始解析程序
func (p *Parser) ParseProgram() *ast.Program {
	program := &ast.Program{}
	program.Statements = []ast.Statement{}

	//循环解析语句
	for !p.curTokenIs(lexer.EOF) {
		stmt := p.parseStatement()
		if stmt != nil {
			program.Statements = append(program.Statements, stmt)
		}
		p.nextToken()
	}

	return program
}

// 开始解析语句
func (p *Parser) parseStatement() ast.Statement {
	switch p.curToken.Type {
	case lexer.LET:
		resultLet := p.parseLetStatement()
		return resultLet
	/* case lexer.IDENT:
	if p.peekTokenIs(lexer.ASSIGN) {
		//判断下一个token是不是等号
		return p.parseAssignStatement()
	} else if p.peekTokenIs(lexer.POINT) {
		//判断下一个token是不是点号.
		return p.parsePointStatement()
	}
	return p.parseExpressionStatement() */
	case lexer.IMPORT:
		return p.parseImportStatement()
	case lexer.RETURN:
		return p.parseReturnStatement()
	default:
		expressionResult := p.parseExpressionStatement()
		return expressionResult
	}
}

// 解析let语句
func (p *Parser) parseLetStatement() *ast.LetStatement {
	stmt := &ast.LetStatement{Token: p.curToken}
	//判断是不是标识符
	if !p.expectPeek(lexer.IDENT) {
		p.appendError("语法错误: %q 无效的标识符", p.curToken.Literal)
		return nil
	}
	//变量名称
	stmt.Name = &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}

	//判断是不是等号
	if !p.expectPeek(lexer.ASSIGN) {
		p.appendError("语法错误: %q 没有定义", p.curToken.Literal)
		return nil
	}

	p.nextToken()

	//判断是不是"引号
	/* if p.curTokenIs(lexer.DOUBLE_QUOTATION_MARK) {
		p.nextToken()
	} */

	stmt.Value = p.parseExpression(LOWEST)

	//判断下一个token是不是;号
	if p.peekTokenIs(lexer.SEMICOLON) {
		p.nextToken()
	}

	return stmt
}

// 解析变量赋值
/* func (p *Parser) parseIdentifierStatement() *ast.IdentifierStatement {
	stmt := &ast.IdentifierStatement{Token: p.curToken}
} */

// 解析=语句
func (p *Parser) parseAssignStatement() *ast.AssignStatement {
	stmt := &ast.AssignStatement{Token: p.curToken}

	//判断是不是等号
	if !p.peekTokenIs(lexer.ASSIGN) {
		p.appendError("语法错误: 缺少=")
		return nil
	}

	//变量名称
	stmt.Name = &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}

	p.nextToken()
	p.nextToken()

	stmt.Value = p.parseExpression(LOWEST)

	//判断下一个token是不是;号
	if p.peekTokenIs(lexer.SEMICOLON) {
		p.nextToken()
	}

	return stmt
}

func (p *Parser) parseIdentifier() ast.Expression {
	return &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}
}

func (p *Parser) parseIntegerLiteral() ast.Expression {
	res := &ast.IntegerLiteral{Token: p.curToken}
	value, err := strconv.ParseInt(p.curToken.Literal, 0, 64)
	if err != nil {
		p.appendError("无法将 %q 解析为整数", p.curToken.Literal)
		return nil
	}

	res.Value = value
	return res
}

func (p *Parser) parseFloatLiteral() ast.Expression {
	res := &ast.FloatLiteral{Token: p.curToken}
	value, err := strconv.ParseFloat(p.curToken.Literal, 64)
	if err != nil {
		p.appendError("无法将 %q 解析为浮点数", p.curToken.Literal)
		return nil
	}

	res.Value = value
	return res
}

func (p *Parser) parseStringLiteral() ast.Expression {
	res := &ast.StringLiteral{Token: p.curToken, Value: p.curToken.Literal}
	return res
}

func (p *Parser) parseBoolean() ast.Expression {
	return &ast.Boolean{Token: p.curToken, Value: p.curTokenIs(lexer.TRUE)}
}

// 解析表达式语句
func (p *Parser) parseExpressionStatement() *ast.ExpressionStatement {
	// fmt.Printf("%+v\n", p.curToken)
	stmt := &ast.ExpressionStatement{Token: p.curToken}
	//判断下一个token是不是.号
	/* if p.curTokenIs(lexer.DOT) {
		p.nextToken()
	} */
	stmt.Expression = p.parseExpression(LOWEST)

	//判断下一个token是不是;号
	if p.peekTokenIs(lexer.SEMICOLON) {
		p.nextToken()
	}

	return stmt
}

// 解析表达式
func (p *Parser) parseExpression(precedence int) ast.Expression {
	prefix := p.prefixParseFns[p.curToken.Type]
	if prefix == nil {
		// p.noPrefixParseFnError(p.curToken.Type)
		p.appendError("语法错误: %q 无效的前缀表达式", p.curToken.Literal)
		return nil
	}

	leftExp := prefix()

	for {
		// 检查是否可能是访问表达式（.）
		if p.peekTokenIs(lexer.DOT) {
			p.nextToken()
			fmt.Println("leftExp:", leftExp)
			// 消耗.
			leftExp = p.parseAccessExpression(leftExp)
			continue
		}
		// 不等于分号; , 下一个token优先级大于当前优先级
		if !p.peekTokenIs(lexer.SEMICOLON) && precedence < p.peekPrecedence() {
			infix := p.infixParseFns[p.peekToken.Type]
			if infix == nil {
				return leftExp
			}

			p.nextToken()

			leftExp = infix(leftExp)
			continue
		}
		break
	}

	return leftExp
}

// 解析模块，对象访问表达式
func (p *Parser) parseAccessExpression(left ast.Expression) ast.Expression {
	/* // 跳过. token
	p.nextToken()

	ae := &ast.AccessExpression{
		Left:     left,
		Property: p.parseIdentifier().(*ast.Identifier),
	}

	// 检查是否是方法调用
	if p.peekTokenIs(lexer.LPAREN) {
		p.nextToken()
		ae.Call = true
		ae.Args = p.parseCallArguments()
	}

	// 链式调用 request.get().status
	if p.peekTokenIs(lexer.DOT) {
		p.nextToken()
		return p.parseAccessExpression(ae)
	} */

	// 确保当前位置是.
	if !p.curTokenIs(lexer.DOT) {
		p.appendError("预期.，得到 %q", p.curToken.Literal)
		return nil
	}

	// 解析属性/方法名
	p.nextToken()
	property := p.parseIdentifier().(*ast.Identifier)

	if property == nil {
		return nil
	}
	ae := &ast.AccessExpression{
		Token:    p.curToken,
		Left:     left,
		Property: property,
	}

	// 检查是否是方法调用（后面有括号）
	if p.peekTokenIs(lexer.LPAREN) {
		p.nextToken() // 消耗(
		ae.Call = true
		ae.Args = p.parseCallArguments()
	}
	return ae
}

// 注册前缀表达式
func (p *Parser) registerPrefix(tokenType lexer.TokenType, fn prefixParseFn) {
	p.prefixParseFns[tokenType] = fn
}

// 注册中缀表达式
func (p *Parser) registerInfix(tokenType lexer.TokenType, fn infixParseFn) {
	p.infixParseFns[tokenType] = fn
}

// 解析中缀表达式
func (p *Parser) parseInfixExpression(left ast.Expression) ast.Expression {
	expression := &ast.InfixExpression{
		Token:    p.curToken,
		Operator: p.curToken.Literal,
		Left:     left,
	}
	//获取当前token优先级
	precedence := p.curPrecedence()

	p.nextToken()

	//获取表达式中右侧的表达式
	expression.Right = p.parseExpression(precedence)
	return expression
}

// 获取当前token优先级
func (p *Parser) curPrecedence() int {
	if p, ok := precedences[p.curToken.Type]; ok {
		return p
	}

	return LOWEST
}

// 获取下一个token优先级
func (p *Parser) peekPrecedence() int {
	if p, ok := precedences[p.peekToken.Type]; ok {
		return p
	}

	return LOWEST
}

func (p *Parser) parseGroupedExpression() ast.Expression {
	p.nextToken()
	exp := p.parseExpression(LOWEST)
	if !p.expectPeek(lexer.RPAREN) {
		return nil
	}

	return exp
}

func (p *Parser) parseReturnStatement() *ast.ReturnStatement {
	stmt := &ast.ReturnStatement{Token: p.curToken}

	p.nextToken()

	stmt.ReturnValue = p.parseExpression(LOWEST)

	if p.peekTokenIs(lexer.SEMICOLON) {
		p.nextToken()
	}

	return stmt
}
func (p *Parser) parseIfExpression() ast.Expression {
	expression := &ast.IfExpression{Token: p.curToken}
	//"("
	if !p.expectPeek(lexer.LPAREN) {
		return nil
	}
	if p.peekTokenIs(lexer.STRING) {
		p.nextToken()
	}
	expression.Condition = p.parseExpression(LOWEST)

	//")"
	if !p.curTokenIs(lexer.RPAREN) {
		return nil
	}

	//{
	if !p.expectPeek(lexer.LBRACE) {
		return nil
	}

	expression.Consequence = p.parseBlockStatement()

	if p.peekTokenIs(lexer.ELSE) {
		p.nextToken()
		/* if p.peekTokenIs(lexer.IF) {
			for p.peekTokenIs(lexer.IF) {
				p.nextToken()
				return p.parseIfExpression()
			}
		} else { */

		if !p.expectPeek(lexer.LBRACE) {
			return nil
		}

		expression.Alternative = p.parseBlockStatement()
		// }
	}

	/* if p.peekTokenIs(lexer.ELSE) {
		p.nextToken()

		if !p.expectPeek(lexer.LBRACE) {
			return nil
		}

		expression.Alternative = p.parseBlockStatement()
	} */

	return expression
}

func (p *Parser) parseForExpression() ast.Expression {
	expression := &ast.ForExpression{Token: p.curToken}

	if !p.expectPeek(lexer.LPAREN) {
		return nil
	}

	p.nextToken()

	//初始值 i=1
	expression.InitialValue = p.parseLetStatement()
	//判断是不是;
	if p.curTokenIs(lexer.SEMICOLON) {
		p.nextToken()
	}

	//条件 i<=5
	expression.Condition = p.parseExpression(LOWEST)

	//判断是不是;
	if p.peekTokenIs(lexer.SEMICOLON) {
		p.nextToken()
		p.nextToken()
	}

	//增量 i++
	expression.Increment = p.parseExpression(LOWEST)

	//判断是不是++
	if p.peekTokenIs(lexer.PLUSPLUS) || p.peekTokenIs(lexer.MINUSMINUS) {
		p.nextToken()
	}

	//)
	if !p.expectPeek(lexer.RPAREN) {

		return nil
	}

	//{
	if !p.expectPeek(lexer.LBRACE) {
		return nil
	}

	expression.Body = p.parseBlockStatement()
	return expression
}

// 解析块语句
func (p *Parser) parseBlockStatement() *ast.BlockStatement {
	block := &ast.BlockStatement{Token: p.curToken}
	block.Statements = []ast.Statement{}
	p.nextToken()

	for !p.curTokenIs(lexer.RBRACE) && !p.curTokenIs(lexer.EOF) {
		stmt := p.parseStatement()
		if stmt != nil {
			block.Statements = append(block.Statements, stmt)
		}
		p.nextToken()
	}

	return block
}

func (p *Parser) parseFunctionLiteral() ast.Expression {
	lit := &ast.FunctionLiteral{Token: p.curToken}
	/* //判断下一个token是不是(
	if !p.expectPeek(lexer.LPAREN) {
		return nil
	} */
	//判断下一个token是不是 IDENT
	if !p.expectPeek(lexer.IDENT) {
		return nil
	}

	lit.Name = p.curToken.Literal
	p.nextToken()

	lit.Parameters = p.parseFunctionParameters()

	if !p.expectPeek(lexer.LBRACE) {
		return nil
	}

	lit.Body = p.parseBlockStatement()

	return lit
}

// 解析函数参数
func (p *Parser) parseFunctionParameters() []*ast.Identifier {

	identifiers := []*ast.Identifier{}
	//判断下一个token是不是)
	if p.peekTokenIs(lexer.RPAREN) {
		p.nextToken()
		return identifiers
	}

	p.nextToken()

	ident := &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}
	identifiers = append(identifiers, ident)

	for p.peekTokenIs(lexer.COMMA) {
		p.nextToken()
		p.nextToken()
		ident := &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}
		identifiers = append(identifiers, ident)
	}

	if !p.expectPeek(lexer.RPAREN) {
		return nil
	}

	return identifiers
}

// 调用解析函数表达式
func (p *Parser) parseCallExpression(function ast.Expression) ast.Expression {
	exp := &ast.CallExpression{Token: p.curToken, Function: function}
	// exp.Arguments = p.parseCallArguments()
	exp.Arguments = p.parseExpressionList(lexer.RPAREN)
	/* //判断下一个token是不是.号
	if p.peekTokenIs(lexer.POINT) {
		fmt.Println("exp.Arguments1:")
		p.nextToken()
		p.nextToken()
	} */
	return exp
}

// 参数
func (p *Parser) parseCallArguments() []ast.Expression {
	list := []ast.Expression{}

	//判断是不是“）”
	if p.peekTokenIs(lexer.RPAREN) {
		p.nextToken()
		return list
	}

	p.nextToken()

	//判断是不是"引号
	/* if p.curTokenIs(lexer.DOUBLE_QUOTATION_MARK) {
		p.nextToken()
	} */
	list = append(list, p.parseExpression(LOWEST))

	//判断下一个token是不是"引号
	/* if p.peekTokenIs(lexer.DOUBLE_QUOTATION_MARK) {
		p.nextToken()
	} */

	for p.peekTokenIs(lexer.COMMA) {
		p.nextToken()
		p.nextToken()
		/* //判断是不是"引号
		if p.curTokenIs(lexer.DOUBLE_QUOTATION_MARK) {
			p.nextToken()
		} */
		list = append(list, p.parseExpression(LOWEST))
		/* //判断下一个token是不是"引号
		if p.peekTokenIs(lexer.DOUBLE_QUOTATION_MARK) {
			p.nextToken()
		} */
	}
	//判断是不是“）”
	if !p.expectPeek(lexer.RPAREN) {
		return nil
	}

	return list
}

// 解析函数参数
func (p *Parser) parseExpressionList(end lexer.TokenType) []ast.Expression {
	list := []ast.Expression{}

	if p.peekTokenIs(end) {
		p.nextToken()
		return list
	}

	p.nextToken()
	// fmt.Println("是这里吗？", p.parseExpression(LOWEST))
	list = append(list, p.parseExpression(LOWEST))

	for p.peekTokenIs(lexer.COMMA) {
		p.nextToken()
		p.nextToken()

		list = append(list, p.parseExpression(LOWEST))
	}

	if !p.expectPeek(end) {
		return nil
	}

	return list
}

// 数组
func (p *Parser) parseArrayLiteral() ast.Expression {
	array := &ast.ArrayLiteral{Token: p.curToken}
	//RBRACKET ]
	array.Elements = p.parseExpressionList(lexer.RBRACKET)

	return array
}

func (p *Parser) parseIndexExpression(left ast.Expression) ast.Expression {
	exp := &ast.IndexExpression{Token: p.curToken, Left: left}

	p.nextToken()
	exp.Index = p.parseExpression(LOWEST)

	//]
	if !p.expectPeek(lexer.RBRACKET) {
		return nil
	}

	//=
	if p.peekTokenIs(lexer.ASSIGN) {
		p.nextToken()
		p.nextToken()
		exp.Right = p.parseExpression(LOWEST)
	}

	return exp
}

func (p *Parser) parseHashLiteral() ast.Expression {
	hash := &ast.HashLiteral{Token: p.curToken}
	hash.Pairs = make(map[ast.Expression]ast.Expression)

	//不是"}"就执行
	for !p.peekTokenIs(lexer.RBRACE) {
		p.nextToken()
		key := p.parseExpression(LOWEST)

		if !p.expectPeek(lexer.COLON) {
			return nil
		}

		p.nextToken()
		value := p.parseExpression(LOWEST)
		hash.Pairs[key] = value

		if !p.peekTokenIs(lexer.RBRACE) && !p.expectPeek(lexer.COMMA) {
			return nil
		}
	}

	//}
	if !p.expectPeek(lexer.RBRACE) {
		return nil
	}

	return hash
}

func (p *Parser) parseImportStatement() ast.Statement {
	if p.curToken.Literal != "import" {
		fmt.Println("不是import")
		// return nil
	}
	imp := &ast.ImportStatement{Token: p.curToken}
	p.nextToken()
	if p.curToken.Type == lexer.SEMICOLON {
		p.nextToken()
	}
	//name := p.parseExpression(LOWEST)
	//获取路径最后的名称
	// lastName := filepath.Base(p.curToken.Literal)
	imp.Name = &ast.Identifier{
		Token: p.curToken,
		Value: p.curToken.Literal,
	}
	imp.Path = p.curToken.Literal
	p.nextToken()
	return imp
}

// 解析模块访问表达式
func (p *Parser) parseModuleAccess(left ast.Expression) ast.Expression {

	expr := &ast.ModuleAccess{
		Token:  p.curToken,
		Module: left.(*ast.Identifier), // 左侧必须是标识符
	}
	// fmt.Println("expr:", *expr)

	p.nextToken() // 跳过 '.'

	expr.Name = &ast.Identifier{
		Token: p.curToken,
		Value: p.curToken.Literal,
	}

	// 设置优先级确保正确解析链式访问如 api.foo.bar
	/* precedence := p.curPrecedence()
	expr.Name = p.parseExpression(precedence) */
	// p.nextToken()
	return expr

	/* func (p *Parser) parseInfixExpression(left ast.Expression) ast.Expression {
	expression := &ast.InfixExpression{
		Token:    p.curToken,
		Operator: p.curToken.Literal,
		Left:     left,
	}
	//获取当前token优先级
	precedence := p.curPrecedence()

	p.nextToken()

	//获取表达式中右侧的表达式
	expression.Right = p.parseExpression(precedence)
	return expression */
}

// 解析属对象属性访问表达式
func (p *Parser) parseDotExpression(left ast.Expression) ast.Expression {
	exp := &ast.DotExpression{
		Token: p.curToken,
		Left:  left,
	}

	p.nextToken()
	exp.Right = p.parseIdentifier().(*ast.Identifier)

	return exp
}

/* func (p *Parser) parseObjectAccess(left ast.Expression) ast.Expression {
	ident := p.parseIdentifier()

	if p.peekTokenIs(token.LPAREN) {
		// 方法调用
		args := p.parseCallArguments()
		return &ast.MethodCall{
			Object:    left,
			Method:    ident,
			Arguments: args,
		}
	}

	// 普通属性访问
	return &ast.ObjectPropertyAccess{
		Object:   left,
		Property: ident,
	}
} */
